<template>
  <div class="roleList">
    <!-- 面包屑 -->
    <el-breadcrumb separator-class="el-icon-d-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>权限列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 添加角色按钮 -->
    <el-button type="success">添加角色</el-button>
    <!-- 表格 -->
    <el-table :data="roleList" style="width: 100%">
      <!-- 这个table-column是前面的小箭头，所以其他表格内容出现在这个下面 -->
      <el-table-column type="expand">
        <template slot-scope="scope">
          <!-- 嵌套循环生成展开的数据展示结构 -->
          <el-row v-for="first in scope.row.children" :key="first.id">
            <el-col :span="4">
              <el-tag
                closable
                :type="'success'"
                @close="cnt=0;delRight(scope.row,first.id)"
              >{{first.authName}}</el-tag>
            </el-col>
            <el-col :span="20">
              <el-row v-for="second in first.children" :key="second.id">
                <el-col :span="4">
                  <el-tag
                    closable
                    :type="'info'"
                    @close="cnt=0;delRight(scope.row,second.id)"
                  >{{second.authName}}</el-tag>
                </el-col>
                <el-col :span="20">
                  <el-tag
                    v-for="third in second.children"
                    :key="third.id"
                    closable
                    :type="'warning'"
                    @close="cnt=0;delRight(scope.row,third.id)"
                  >{{third.authName}}</el-tag>
                </el-col>
              </el-row>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24" v-show="scope.row.children.length === 0">还没有任何的权限，先分配！！</el-col>
          </el-row>
        </template>
      </el-table-column>
      <el-table-column type="index" width="50"></el-table-column>
      <el-table-column prop="roleName" label="角色名称" width="180"></el-table-column>
      <el-table-column prop="roleDesc" label="描述" width="180"></el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-tooltip content="编辑" placement="top" effect="dark">
            <el-button type="primary" icon="el-icon-edit"></el-button>
          </el-tooltip>
          <el-tooltip content="角色授权" placement="top" effect="dark">
            <el-button type="success" icon="el-icon-setting" @click="showGrantDialog(scope.row)">></el-button>
          </el-tooltip>
          <el-tooltip content="删除" placement="top" effect="dark">
            <el-button type="warning" icon="el-icon-delete"></el-button>
          </el-tooltip>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分配权限dialog -->
    <el-dialog title="权限分配" :visible.sync="grantDialogTableVisible">
      <el-tree
        :data="rightList"
        ref='tree'
        show-checkbox
        node-key="id"
        :default-expand-all="true"
        :default-checked-keys="chkedArr"
        :props="defaultProps"
      ></el-tree>
      <div slot="footer" class="dialog-footer">
        <el-button @click="grantDialogTableVisible = false">取 消</el-button>
        <el-button type="primary" @click="grantRole">确 定</el-button>
      </div>
    </el-dialog>
    <!-- end roleList -->
  </div>
</template>

<script>
import { getRoleList, delRightByRoleId, grantRoleById } from '@/api/role_index.js'
import { getRightList } from '@/api/right_index.js'
export default {
  data () {
    return {
      // 用于存储角色的id，在角色授权的时候能有对应的角色id使用
      roleId: '',
      // 在进行权限删除的时候，防止弹出太多提示框而设置的flag
      cnt: 0,
      // 是否显示分配权限dialog的flag
      grantDialogTableVisible: false,
      defaultProps: {
        // 当前tree节点显示给用户看的内容
        label: 'authName',
        // 当前tree节点的下一个节点
        children: 'children'
      },
      // 当前角色所有拥有的id，就是tree中默认选中的
      chkedArr: [],
      // 权限数据展开的数据源
      roleList: [],
      rightList: []
    }
  },
  methods: {
    // 实现角色授权
    // async:标记这个函数会有异步操作，await需要绑定async使用
    async grantRole () {
      // 看elementUI的文档有多个函数能获取key数据，但是经过console.log之后发现只有getCheckedNodes合适
      // 栗子，1.有：[{id:109,pid:'107,102'},{id:154,pid:'107,102'}]
      let arr = this.$refs.tree.getCheckedNodes()
      // 2.遍历数组，拼接数据，我觉得可以用forEach啊
      let temp = []
      for (var i = 0; i < arr.length; i++) {
        temp.push(arr[i].id + ',' + arr[i].pid) //  ["109,107,102","154,107,102"]
      }
      // 3.拼接数组元素然后有转化为数组，因为es新语法new set()可以去重
      temp = temp.join(',').split(',') // [109,107,102,154,107,102]
      // 4.new set(arr)数组去重
      temp = [...new Set(temp)]
      // 接下来是我们需要把授权的信息发送给服务器，这是异步操作。使用es7新语法async和await组合
      // await必须写在async标记的函数内，即await所在函数前头必须有async标记
      // 本来这里应该是.then和.catch
      let res = await grantRoleById(this.roleId, temp.join(','))
      console.log(res)
      if (res.data.meta.status === 200) {
        this.$message.success(res.data.meta.msg)
        this.grantDialogTableVisible = false
        this.init()
      } else {
        this.$message.error(res.data.meta.msg)
      }
    }, /* end grantRole */
    // 显示权限分配dialog
    showGrantDialog (row) {
      // 进行数据存储为了后期角色授权时可以获得角色id
      this.roleId = row.id
      // 1.让对话框展示
      // 2.加载树形组件的数据
      // 3.获取权限id，让节点默认被选择
      this.grantDialogTableVisible = true
      // 加载树形组件数据,这个树形组件的加载本可以在加载mounted里加载的，但是由于树形组件的特性，默认加载缓存的数据，所以需要修改
      getRightList('tree').then(res => {
        this.rightList = res.data.data
      })
      // 加载完之后重置数据数组
      this.chkedArr.length = 0
      // 获取当前角色的所有权限id,添加到chkedArr
      // 只需要获取最后一级就可以了，我们之前已经在删除权限的时候做了删除没有子权限的权限，但是这里还是尽量做一个判断，以保证万无一失
      row.children.forEach(first => {
        if (first.children.length > 0) {
          first.children.forEach(second => {
            if (second.children.length > 0) {
              second.children.forEach(third => {
                // 判断完都有子权限之后，再将idpush
                this.chkedArr.push(third.id)
              })
            }
          })
        }
      })
    },
    // 删除角色展开的权限
    delRight (row, rightId) {
      console.log(row.id, rightId)
      delRightByRoleId(row.id, rightId)
        .then(res => {
          console.log(res)
          if (res.data.meta.status === 200) {
            if (this.cnt === 0) {
              this.$message.success(res.data.meta.msg)
              this.cnt++
            }
            // 清空表单元素数据，重置表单元素
          }
          // 刷新,不要使用init，因为init会刷新整个表格，造成展开行合并
          //   this.init()
          // res.data.data就是实现当前权限删除操作后该角色还拥有的权限数据
          // 为了避免刷新整个表格，我们可以将这个数据重置当前角色的展开行数据
          // 展开行数据：scope.row.children
          row.children = res.data.data
          // 下面写的代码多次调用了自己，可以进行递归的优化
          row.children.forEach((v1, in1) => {
            // 遍历一级权限
            console.log(row)
            if (v1.children.length === 0) {
              // 说明这个一级权限下没有任何二级权限
              this.delRight(row, v1.id)
            } else {
              v1.children.forEach((v2, in2) => {
                // 遍历二级权限
                if (v2.children.length === 0) {
                  // 说明这个二级权限下面没有任何的三级权限
                  this.delRight(row, v2.id)
                }
              })
            }
          })
        })
        .catch(err => {
          console.log(err)
        })
    },
    init () {
      getRoleList().then(res => {
        console.log(res)
        if (res.data.meta.status === 200) {
          this.roleList = res.data.data
        }
      })
    }
  },
  mounted () {
    // 一进来就先mounted
    this.init()
    // getRightList('tree').then(res => {
    //   console.log(res)
    //   this.rightList = res.data.data
    // })
  }
}
</script>

<style lang="less" scoped>
</style>
